1. NodeBox 1
    1. Homepage
    2. NodeBox 3Node-based app for generative design and data visualization
    3. NodeBox OpenGLHardware-accelerated cross-platform graphics library
    4. NodeBox 1Generate 2D visuals using Python code (Mac OS X only)
  2. Gallery
  3. Documentation
  4. Forum
  5. Blog

Cars | source code

size(1280,800)
speed(50)
from math import *
from nodebox.geo import *
 
try: 
    tuio = ximport("tuio")
except:
    tuio = ximport("__init__")
    reload(tuio)
global tracking
 
class Remote:
    '''the remote is actually the car . It has a few variables (speed,
    color and gets information from the fiducials placed on the table
    every car has a checkpointlist which keeps the player informed about
    its current status.'''
    def __init__(self, x, y,sx,sy,speeder,list,yy):
        self.x, self.y = x, y
        self.sx,self.sy = sx,sy
        self.size = 15.0
        self.speeder = speeder
        self.list = list
        self.mycplist = []
        self.yy = yy
        self.a = 0
        self.kleur = color(random(.6,1.0),random(.6,1.0),0)
        for i in range(len(self.list)):
            self.xT = 100+i*20
            self.yT = self.yy
            self.bT = 15
            boT = False
            all = self.xT,self.yT,self.bT,boT
            self.mycplist.append(all)    
 
    def draw(self):
        self.sx = self.speeder*cos(radians(self.a))
        self.sy = self.speeder*sin(radians(self.a))
        self.x+=self.sx
        self.y+=self.sy
        stroke(0);strokewidth(2);fill(self.kleur)
        oval(self.x-self.size, self.y-self.size, self.size*2, self.size*2) 
        for data in self.mycplist:
            if not data[3] == False:
                fill(self.kleur)
            else:
                fill(1)
            oval(data[0],data[1],data[2],data[2])
 
class Arena:
    '''the arena consists of 2 paths. the arena itself and 
    a path which is the 'center' of the previous path and which
    is  used to create certain checkpoints'''
    def __init__(self,pad):
        self.pad = pad
        self.midpad = None
        forms = (oval,rect)
        a = 4+random(4)
        for i in range(a):
            r = 200+random(200)
            x = (300-a*15)+i*100
            y = HEIGHT/2-r/2+random(-100,100)
            f = choice(forms)
            xx = (x+(x+r/4))/2
            yy = (y+(y+r/4))/2
            b = (r+(r/2))/2
 
            segA = f(x,y,r,r)
            segB = f(x+r/4,y+r/4,r/2,r/2)
            mseg = f(xx,yy,b,b)
            seg = segA.xor(segB)
            
            if not self.pad and r>250:
                self.pad = seg
            if not self.midpad:
                self.midpad = mseg
                
            self.pad = self.pad.union(seg)
            self.midpad = self.midpad.union(mseg)
        self.checkpoints()
            
    def linedash(self,path,segment=20,gap=10):
        path._nsBezierPath.setLineDash_count_phase_([segment,gap],2,0)
        return path        
        
    '''create a list of checkpoints  '''  
    def checkpoints(self):
        self.pList = []
        num = 0
        for path in self.midpad:
            s = 20
            #startcp
            if num == 0:
                cp = path.x,path.y,num
                self.pList.append(cp)
            #other cps
            if num%10==0 and num>0 and num:
                cp = path.x,path.y,num
                self.pList.append(cp)
            num+=1
        return self.pList
        
    '''update checkpoint in checkpointlist  from each car/remote based on 
    distance from the car in relation to the checkpoint'''     
    def cpmatrix(self,remote):
        
        n = 0
        for item in self.pList:
            dis = distance(item[0],item[1],remote.x,remote.y)
            #remove color from checkpoints when over startcp
            if n == 0:
                if dis < 30:
                    for i in range(len(self.pList)):
                        t = False
                        xt = 100+i*20
                        remote.mycplist[i] = xt,remote.yT,remote.bT,t
            #color the checkpoint 
            if dis < 30:
                t = True
                xt = 100+n*20
                remote.mycplist[n] = xt,remote.yT,remote.bT,t
            n+=1 
             
    '''draw checkpoints   ''' 
    def drawcp(self):
        g = 20
        n = 0
        fontsize(20)
        for item in self.pList:
            fill(0);strokewidth(2)
            c = 30
            oval(item[0]-c/2,item[1]-c/2,c,c)
            #fill(1)
            #text(n,item[0]-(textwidth(n)/2),item[1]+(textheight(n)/4))
            n+=1
            
    '''draw the arena, the checkpoints and the centerpath in a nice dashed 
    line (as found on the website tutorial section'''    
    def draw(self):
        fill(0.59,0.64,0.53)
        stroke(0);strokewidth(3)
        drawpath(self.pad)
        d = self.linedash(self.midpad)
        nofill();stroke(1)
        drawpath(d)
        self.drawcp()
 
'''function for building/rebuilding the needed components. rebuiling
because placing a certain fiducial (zero) enables  the arena to be
recreated'''      
def built():  
    global tracking,ar,cars,muisdown 
    ar = Arena(None)
    cars = []
    aantalcars = 2
    for i in range(aantalcars):
        xx,yy = ar.midpad[0].x,ar.midpad[0].y
        remote = Remote(xx,yy,2,2,1,ar.pList,100+i*20)
        cars.append(remote)
    muisdown = False    
    
def setup():
    global tracking
    built()
    tracking = tuio.Tracking()
 
'''start marker''' 
def signs():
    global ar
    fontsize(14)
    aantal = len(ar.midpad)
    fill(0);stroke(0);strokewidth(1)
    line(ar.midpad[0].x,ar.midpad[0].y,ar.midpad[0].x+100,ar.midpad[0].y+100)
    text("START",ar.midpad[0].x+100,ar.midpad[0].y+100)
    
def draw():
    font("Courier Bold",20)
    global tracking,ar,cars,muisdown
    tracking.update()
    #the numbers refer to the fiducial-numbers
    for obj in tracking.objects():
        if obj.id == 1:
            cars[0].a = obj.angle
        elif obj.id == 4:
            cars[1].a = obj.angle
        elif obj.id == 12:
            cars[2].a = obj.angle
        elif obj.id == 81:
            muisdown = True
    if muisdown:
        built()
    path = ar.pad
    ar.draw()
    signs()
    for remote in cars:
        ar.cpmatrix(remote)
        if path.contains(remote.x,remote.y):
            remote.speeder = 4.0        
        else:
            remote.speeder=1.0
        remote.draw()
 
def stop():
    global tracking
    tracking.stop()